#define __pGetVar(pvarname) (player getVariable #pvarname)
#define __pSetVar player setVariable

if (d_string_player in d_is_engineer) then {
	x_sfunc = {
		private ["_objs"];
		if ((vehicle player) == player)then{_objs = nearestObjects [player,["LandVehicle","Air"],5];if (count _objs > 0) then {d_objectID2 = _objs select 0;if (alive d_objectID2) then {if(damage d_objectID2 > 0.05 || fuel d_objectID2<1)then{true}else{false}}else{false}}}else{false};
	};
};

XIncomingMissile = {
	private ["_vehicle", "_ammo", "_who", "_missile", "_flare", "_flares"];
	_vehicle = _this select 0;
	if (!isEngineOn _vehicle || isNull (driver _vehicle) || !alive _vehicle) exitWith {};
	_ammo = _this select 1;
	_who = _this select 2;

	_missile = nearestObject [_who,_ammo];

	if (isNull _missile) exitWith {};
	
	// TODO : add somethng here if possible
	//[_vehicle, localize "MSG_DOM_DROPPINGFLARES"] call XfVehicleChat;
	//["d_flav", _vehicle] call XNetCallEvent;

	if ((random 100) >= 40) then {
		waitUntil {(_missile distance _vehicle) <= 170};
		deletevehicle _missile;
	} else {
		waitUntil {(_missile distance _vehicle) <= 100};
		[_vehicle, localize "MSG_DOM_MISSILEIMPACT"] call XfVehicleChat;
	};
};

if (d_string_player in d_is_medic) then {
	XMashKilled = {
		private ["_mash","_m_name","_mash_available","_mash_player"];
		_mash = _this select 0;
		_mash_player = __pGetVar ["medic_tent", objNull];
		if (_mash_player != _mash) exitWith {};
		_m_name = format [localize "MSG_DOM_MASHMRK", str(player)];
		deleteMarker _m_name;
		__pSetVar ["d_medtent", []];
		localize "MSG_DOM_MASHDESTROYED" call XfGlobalChat;
		if (!isNull _mash) then {deleteVehicle _mash};
		["d_p_o_r", [str(player),_m_name]] call XNetCallEvent;
		__pSetVar ["medic_tent", objNull];
		_mash_available = player getVariable "d_medtent_available";
		if (isnil "_mash_available") then {_mash_available = 1;};
		player setVariable ["d_medtent_available", (_mash_available - 1)];
	};
};

if (d_string_player in d_can_use_mgnests) then {
	XMGnestKilled = {
		private ["_mgnest","_m_name","_mgnest_available","_mgnest_player"];
		_mgnest = _this select 0;
		_mgnest_player = __pGetVar ["mg_nest", objNull];
		if (_mgnest_player != _mgnest) exitWith {};
		_m_name = format [localize "MSG_DOM_MGNESTMRK", str(player)];
		["d_w_ma",_m_name] call XNetCallEvent;
		__pSetVar ["d_mgnest_pos", []];
		localize "MSG_DOM_MGNESTDESTROYED" call XfGlobalChat;
		if (!isNull _mgnest) then {deleteVehicle _mgnest};
		["d_p_o_r", [str(player),_m_name]] call XNetCallEvent;
		__pSetVar ["mg_nest", objNull];
		_mgnest_available = player getVariable "d_mgnest_available";
		if (isnil "_mgnest_available") then {_mgnest_available = 1;};
		player setVariable ["d_mgnest_available", (_mgnest_available - 1)];
	};
};

if (d_string_player in d_can_use_aapods) then {
	XAAPodKilled = {
		private ["_aapod","_m_name","_aapod_available","_aapod_player"];
		_aapod = _this select 0;
		_aapod_player = __pGetVar ["aa_pod", objNull];
		if (_aapod_player != _aapod) exitWith {};
		_m_name = format [localize "MSG_DOM_AAMRK", str(player)];
		["d_w_ma",_m_name] call XNetCallEvent;
		__pSetVar ["d_aapod_pos", []];
		localize "MSG_DOM_AADESTROYED" call XfGlobalChat;
		if (!isNull _aapod) then {deleteVehicle _aapod};
		["d_p_o_r", [str(player),_m_name]] call XNetCallEvent;
		__pSetVar ["aa_pod", objNull];
		_aapod_available = player getVariable "d_aapod_available";
		if (isnil "_aapod_available") then {_aapod_available = 1;};
		player setVariable ["d_aapod_available", (_aapod_available - 1)];
	};
};

XGreyText = {"<t color='#f0bfbfbf'>" + _this + "</t>"};
XRedText = {"<t color='#f0ff0000'>" + _this + "</t>"};
XBlueText = {"<t color='#f07f7f00'>" + _this + "</t>"}; //olive
XPurpleText = {"<t color='#f05555ff'>" + _this + "</t>"}; //Blue purple
XGreenText = {"<t color='#f031723A'>" + _this + "</t>"}; //Forest Green
XLightGreenText = {"<t color='#f031E03A'>" + _this + "</t>"}; //Shiny Green

XfPlacedObjAn = {
	if (str(player) == _this) then {
		if (d_player_is_medic) then {
			_m_name = format [localize "MSG_DOM_MASHMRK", _this];
			["d_w_ma",_m_name] call XNetCallEvent;
			__pSetVar ["d_medtent", []];
			_medic_tent = __pGetVar(medic_tent);
			if (!isNil "_medic_tent") then {if (!isNull _medic_tent) then {deleteVehicle _medic_tent}};
			__pSetVar ["medic_tent", objNull];
		};
		if (d_player_can_build_mgnest) then {
			_m_name = format [localize "MSG_DOM_MGNESTMRK", _this];
			["d_w_ma",_m_name] call XNetCallEvent;
			__pSetVar ["d_mgnest_pos", []];
			_mg_nest = __pGetVar(mg_nest);
			if (!isNil "_mg_nest") then {if (!isNull _mg_nest) then {deleteVehicle _mg_nest}};
			__pSetVar ["mg_nest", objNull];
			localize "MSG_DOM_MGNESTDESTROYED" call XfGlobalChat;
		};
	};
};

XBaseEnemies = {
	private "_status";
	_status = _this select 0;
	switch (_status) do {
		case 0: {
			hint composeText[
				parseText("<t color='#f0ff0000' size='2'>" + localize "MSG_DOM_BASEDANGER" + "</t>"), lineBreak,
				parseText("<t size='1'>" + localize "MSG_DOM_BASEENEMIES" + "</t>")
			];
		};
		case 1: {
			hint composeText[
				parseText("<t color='#f00000ff' size='2'>" + localize "MSG_DOM_BASECLEAR" + "</t>"), lineBreak,
				parseText("<t size='1'>" + localize "MSG_DOM_BASENOENEMIES" + "</t>")
			];
		};
	};
};
	
XFacAction = {
	private ["_num","_thefac","_element","_posf","_facid","_exit_it"];
	_num = _this select 0;
	_thefac = switch (_num) do {
		case 0: {"d_jet_serviceH"};
		case 1: {"d_chopper_serviceH"};
		case 2: {"d_wreck_repairH"};
	};
	waitUntil {(sleep 0.521 + (random 0.3));(X_JIPH getVariable _thefac)};
	_element = d_aircraft_facs select _num;
	_posf = _element select 0;
	sleep 0.543;
	_facid = -1;
	_exit_it = false;
	while {!_exit_it} do {
		sleep 0.432;
		switch (_num) do {
			case 0: {if ((["d_jet_s_reb",False] call XNetGetJIP)) then {_exit_it = true}};
			case 1: {if ((["d_chopper_s_reb",False] call XNetGetJIP)) then {_exit_it = true}};
			case 2: {if ((["d_wreck_s_reb",False] call XNetGetJIP)) then {_exit_it = true}};
		};

		if (!_exit_it) then {
			if (player distance _posf < 14 && (X_JIPH getVariable _thefac) && _facid == -1) then {
				if (alive player) then {
					_facid = player addAction [localize "MSG_DOM_BASEREBUILDSUPPORT" call XRedText,"client\x_rebuildsupport.sqf",_num];
				};
			} else {
				if (_facid != -1) then {
					if (player distance _posf > 13 || !(X_JIPH getVariable _thefac)) then {
						player removeAction _facid;
						_facid = -1;
					};
				};
			};
		} else {
			if (_facid != -1) then {player removeAction _facid};
		};
	};
};

XfTeleport = {
	private ["_list","_veh","_speed","_speed_mps","_vec_x","_vec_y","_vec_dir","_is_targeted","_target","_dir","_pos"];
	_is_targeted = false;
	// This is the case when we give more options to the teleport function.
	// In such a case, the input format is: [[unit list],[target pos]]
	_list = _this;
	if (typename(_this select 0) == "ARRAY") then {
		_list = _this select 0;
		_pos = _this select 1;
		_dir = getDir (vehicle player);
		_is_targeted = true;
	};
	If (!X_Client) exitWith{diag_log "Teleport: Not a client";};
	if (!((vehicle player) in _list)) exitWith{diag_log "Teleport: Player not in the list"};
	if (!_is_targeted) then {
		If (vehicle player == player) exitWith{diag_log "Teleport: Player not in a vehicle";};
		If (isNil "MissionStartTeleporter") exitWith {diag_log "Teleport: No mission start object";};
		If ((getPos MissionStartTeleporter select 0 == 0) And (getPos MissionStartTeleporter select 1 == 0)) exitWith {diag_log "Teleport: Mission Start object position not valid";};
		_pos = getPos MissionStartTeleporter;
		_dir = getDir MissionStartTeleporter;
	};
	if (surfaceiswater [(_pos select 0), (_pos select 1)]) exitWith {diag_log "Teleport: Mission Start object on water";};
	titleText["","BLACK IN"];
	_veh = vehicle player;
	if ((_pos distance _veh) > 150) then {
		_speed = speed _veh;
		_speed_mps = _speed / 3.6;
		diag_log Format["Teleport: Vehicle type: %1", typeof _veh];
		if (driver (vehicle player) == player) then {
			diag_log "Teleport: the player is the driver";
			_vec_dir = _dir;
			_vec_x = (sin _vec_dir) * _speed_mps;
			_vec_y = (cos _vec_dir) * _speed_mps;
			_veh setPos (_pos);
			_veh setDir (_vec_dir);
			_veh setVelocity [_vec_x, _vec_y, 0];
		};
		titleFadeOut 0.5;
	} else {
		_player vehicleChat (localize "MSG_DOM_TELEPORTTOOCLOSE");
	};
};

XfAirTaxiAvailable = {
	private ["_player","_air_taxis","_result"];
	_result = true;
	_player = player;
	_air_taxis = ["airtaxi_available",[]] call XNetGetJIP;
	if (isNil "_air_taxis") then {_air_taxis=[]};
	if (typeName _air_taxis != "ARRAY") then {_air_taxis=[]};
	// diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"playerfunctions.sqf","XfAirTaxiAvailable",_air_taxis];
	if (_player in _air_taxis) then {_result = false;};
	_result;
};

xf_ffunc = {
	private ["_l","_vUp","_winkel"];
	if (vehicle player == player) then {
		dm_objectID1 = position player nearestObject "LandVehicle";
		if (!alive dm_objectID1 || player distance dm_objectID1 > 8) then {
			false
		} else {
			_vUp = vectorUp dm_objectID1;
			if ((_vUp select 2) < 0 && ((!isnull ([position player,d_rep_truck,20] call XfNearestObject)) || d_can_flip_without_truck)) then {
				true
			} else {
				_l=sqrt((_vUp select 0)^2+(_vUp select 1)^2);
				if (_l != 0) then {
					_winkel = (_vUp select 2) atan2 _l;
					(_winkel < 30 && ((!isnull ([position player,d_rep_truck,20] call XfNearestObject)) || d_can_flip_without_truck))
				}
			}
		}
	} else {
		false
	}
};